#include <Arduino.h>
#include "SensorData.h"
#include "SimpleMap.h"
#include "global.h"
#include "ActionCtrl.h"
#include "bucket_plant_water/bucket_plant_water.h"
#include "CondNotice.h"
#include "utils.h"
#include "queue.h"
#include "ntc.h"

bool isWaterVal = false;
bool isPumpIdleVal = false;
bool isPumpOverloadVal = false;



class SensorData;

SimpleMap<String, SensorData *> *sensorMap;
class SensorData
{
private:
    String id;
    float sensorValue;
    Queue queue;

public:
    SensorData(String id)
    {
        this->id = id;
    }

    void addSensorData(long value)
    {
        queue.forceEnqueue(value);
    }

    float getValue()
    {
        return queue.average();
    }

    void setSensorValue(float val)
    {
        sensorValue = val;
    }

    String getId()
    {
        return id;
    }

    void setId(String id)
    {
        this->id = id;
    }

    void print()
    {
        // printStr("sensorValue", sensorValue);
    }

    SensorData(/* args */) {

    };
    ~SensorData()
    {
    }
};

void pumpOverloadCb(String i)
{
    setPumpPause(false);
}

void callback(String s)
{
    int vccPinValue = getVccPinValue();
    int tempPinValue = getTempPinValue();
    int waterPinValue = getWater();

    SensorData *temp = sensorMap->get("temp");
    temp->addSensorData(tempPinValue);

    if (!isPump())
    {
        SensorData *vcc = sensorMap->get("vcc");
        vcc->addSensorData(vccPinValue);
    }

    
        SensorData *water = sensorMap->get("water");
        water->addSensorData(waterPinValue);
        
        if (waterPinValue >= 4090)
        {
            if (!isWater())
            {
                setWater(true);
                setSendData(true);
                printStr("有水提醒");
            }
        }
        else
        {
            if (isWater())
            {
                printStr("缺水提醒,发送通知");
                setWater(false);
                setSendData(true);
                addLackWaterNotice();
            }
        }
    
// 检测水泵是否空转

bool   isIdle =   checkPumpIdle();
if( isIdle && (!isPumpIdle()))
{
    printStr("水泵空转");
    setPumpIdle(true);
    addPumpIdleNotice();
}
// // 检测水泵是否过载
// bool isOverload = checkPumpOverload();
// if (isOverload && (!isPumpOverload()))
// {
//     printStr("水泵过载");
//     setPumpOverload(true);
//     addOverloadNotice();
// }

// if(isOverload){
//     setPumpPause(true);
//     excuteDelay(5,"pumpoverload",pumpOverloadCb);
// }

// setPumpPause(isOverload);
}

bool isWater()
{
    return isWaterVal;
}

void setWater(bool b)
{
    isWaterVal = b;
}
float getCurrentVcc()
{
    int vcc = getVccPinValue();

    // float value = convertSensorData("vcc", vcc);
    float value = convertVcc(vcc);
    return value;
}

// 获取端口的adc 平均值
float getSensorPinValue(String id)
{
    if(sensorMap==nullptr){
        return 0.0;
    }
    if (!sensorMap->has(id))
    {
        return false;
    }
    SensorData *data = sensorMap->get(id);
    if(data==nullptr){
        return 0.0;
    }
    //  printStr("计算的数值", data->getValue());
    return data->getValue();
}

float convertSensorData(String id, float value)
{
    if (id.equals("temp"))
    {
        return readNTC();
    }
    else if (id.equals("vcc"))
    {

        return convertVcc(value);
    }
    else if (id.equals("water"))
    {
        return value / 4096;
    }
}

bool getSensorValue(String id, float &value)
{
    if (!sensorMap->has(id))
    {
        return false;
    }
    SensorData *data = sensorMap->get(id);
    //  printStr("计算的数值", data->getValue());
    float tempValue = data->getValue();
    value = convertSensorData(id, tempValue);
    return true;
}

void setupSensorData()
{
    if (sensorMap != nullptr)
    {
        delete sensorMap;
    }

    sensorMap = new SimpleMap<String, SensorData *>([](String &a, String &b) -> int
                                                    {
        if (a == b) return 0;
        if (a > b) return 1;
        /*if (a < b) */ return -1; });

    SensorData *s1 = new SensorData("temp");
    SensorData *s2 = new SensorData("vcc");
    SensorData *s3 = new SensorData("water");

    sensorMap->put("temp", s1);
    sensorMap->put("vcc", s2);
    sensorMap->put("water", s3);

    addGlobalTimerCallBack("sensor_data", callback);
}

void setPumpIdle(bool b)
{
    isPumpIdleVal = b;
}

bool isPumpIdle()
{
    return isPumpIdleVal;
}

bool isPumpOverload()
{
    return isPumpOverloadVal;
}

void setPumpOverload(bool b)
{
    isPumpOverloadVal = b;
}